package aerolineasAdapters;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import aOrganizar.Aerolinea;
import aOrganizar.Asiento;
import aOrganizar.Usuario;
import aOrganizar.Vuelo;

import com.lanchita.AerolineaLanchita;

import excepciones.ComprarException;
import excepciones.ReservarException;
import fechas.FechaUtils;

public class AeroLanchitaAdapter implements Aerolinea {

	
	private static final Double RECARGO_LANCHITA = 1.15;
	private Map<String,String> mapCiudades= new HashMap<String,String>();

	
	
	private static AerolineaLanchita aerolinea = AerolineaLanchita
			.getInstance();
	
	/**
	 * Constructores
	 */
	
	public AeroLanchitaAdapter(){
		this.loadMapaCiudades();
	}

	/**
	 * Acciones
	 */
	
	public void comprar(Asiento asiento, Usuario user) throws ComprarException {
		try {
			aerolinea.comprar(asiento.getNumeroDeAsiento());
		} catch (Exception e) {
			throw new ComprarException(asiento);
		}

	}


	public void reservar(Asiento asiento, Usuario user)
			throws ReservarException {
		try {
			aerolinea.reservar(asiento.getNumeroDeAsiento(), user.getDni());
		} catch (Exception e) {
			throw new ReservarException(asiento);
		}

	}

	public Collection<Asiento> findAsientosByOrigenYDestino(String origen,
			String destino, Date fecha, Usuario usuario) {
		String[][] asientosDisponibles = this.getAsientosDisponibles();
		List<Asiento> listAsiento = (List<Asiento>) parsearAsientos(
				asientosDisponibles, usuario);
		return filtrarByOrigenYDestino(origen, destino, fecha, listAsiento);
	}

	public Collection<Asiento> findAsientosByOrigen(String origen, Date fecha,
			Usuario usuario) {
		String[][] asientosDisponibles = this.getAsientosDisponibles();
		List<Asiento> listAsiento = (List<Asiento>) parsearAsientos(
				asientosDisponibles, usuario);
		return filtrarByOrigenAsientos(origen, fecha, listAsiento);

	}

	/**
	 * Parsea los asientos de String Array a ArrayList
	 * 
	 * @param asientos
	 *            Asientos que se quieren parsear
	 * @return
	 */

	private Collection<Asiento> parsearAsientos(String[][] asientos,
			Usuario usuario) {
		int i = 0;
		List<Asiento> listAsientos = new ArrayList<Asiento>();
		for (i = 0; i < asientos.length; i++) {
			String numeroDeVuelo = asientos[i][0].substring(0, 6);
			Vuelo vueloaux = new Vuelo(numeroDeVuelo, this.getCiudad(asientos[i][8]),
					 this.getCiudad(asientos[i][9]),
					FechaUtils.fechaConHorasYMinutos(asientos[i][11],
							asientos[i][7]), FechaUtils.fechaConHorasYMinutos(
							asientos[i][10], asientos[i][6]), this);
			Asiento asientoAux = new Asiento(asientos[i][2], asientos[i][0],
					Double.valueOf(asientos[i][1]), asientos[i][3], vueloaux,
					asientos[i][4], usuario);

			listAsientos.add(asientoAux);
		}
		return listAsientos;
	}

	private String[][] getAsientosDisponibles() {
		String[][] asientosDisponibles = aerolinea.asientosDisponibles(null,
				null, null, null, null, null);
		return asientosDisponibles;
	}

	private Collection<Asiento> filtrarByOrigenAsientos(String origen,
			Date fecha, Collection<Asiento> colAsientos) {
		ArrayList<Asiento> listAsiento = new ArrayList<Asiento>();
		for (Asiento asiento : colAsientos) {
			if (asiento.getVuelo().getOrigen().equalsIgnoreCase(origen)
					&& FechaUtils.comparar(asiento.getVuelo().getSalida(),
							fecha) == 0)
				listAsiento.add(asiento);
		}
		return listAsiento;
	}

	private Collection<Asiento> filtrarByOrigenYDestino(String origen,
			String destino, Date fecha, Collection<Asiento> colAsientos) {
		ArrayList<Asiento> listAsiento = new ArrayList<Asiento>();
		for (Asiento asiento : colAsientos) {
			if (asiento.getVuelo().getOrigen().equalsIgnoreCase(origen)
					&& asiento.getVuelo().getDestino()
							.equalsIgnoreCase(destino)
					&& FechaUtils.comparar(asiento.getVuelo().getSalida(),
							fecha) == 0)
				listAsiento.add(asiento);
		}
		return listAsiento;

	}
	
	private void loadMapaCiudades(){
		this.mapCiudades.put("USA", "USA");
		this.mapCiudades.put("BUE", "EZE");
		this.mapCiudades.put("EZE", "BUE");
		this.mapCiudades.put("PER", "PER");
		this.mapCiudades.put("USH", "USH");
		this.mapCiudades.put("CABA","AEO");
		this.mapCiudades.put("AEO","CABA");
	}
	
	
	/**
	 * Getters
	 */
	
	public Double getRecargo() {
		return AeroLanchitaAdapter.RECARGO_LANCHITA;
	}
	
	public String getCiudad(String ciudad) {
		return (this.mapCiudades.get(ciudad)!=null? this.mapCiudades.get(ciudad): "");
	}	
	
	public String getNombre(){
		return "Lanchita";
	}

}